import { isEmpty, get } from 'lodash-es';
import { defineStore } from 'pinia';
import { USER_MENUS_KEY } from '../config/index.js';
import { handleCommonRes } from '../utils/resolver';
import { flattenDeep, replaceFields } from '../utils/index.js';
import vueGlobal from '../vueGlobal.js';
import storage from '../utils/storage.js';
import { getStoreId } from './utils.js';

function trim(str) {
  return String(str).trim();
}

export function getPermissionKeyPathEnum() {
  return vueGlobal.get('$router', (router) => {
    const routes = router.getRoutes();
    return routes.reduce((res, route) => {
      let idf = get(route, 'meta.permission');
      let path = get(route, 'path');
      if (!idf) return res;
      if (!Array.isArray(idf)) {
        idf = [idf];
      }
      idf.forEach((key) => {
        Object.assign(res, {
          [key]: path === '/frame' ? `/frame?permission=${key}` : path,
        });
      });
      return res;
    }, {});
  });
}

export function getKeyMenuDataEnum(list = []) {
  const deep = function (list, res) {
    if (!list || !list.length) return res;
    return list.reduce((res, item) => {
      if (!item) return res;
      deep(item.children, res);
      return Object.assign(res, { [item.key]: item });
    }, res);
  };
  return deep(list, {});
}

export function getRouterKeyDataEnum(list = []) {
  const deep = function (list, res) {
    if (!list || !list.length) return res;
    return list.reduce((res, item) => {
      if (!item) return res;
      deep(item.children, res);
      return Object.assign(res, { [item.path]: item.key });
    }, res);
  };
  return deep(list, {});
}

export function getMenuDataGetter() {
  let dataSource = this || {};
  let key, value, field;
  if (arguments.length < 3) {
    [key, field] = arguments;
    const data = get(dataSource, key) || {};
    return field !== undefined ? get(data, field) : data;
  } else {
    [key, value, field] = arguments;
    for (const id in dataSource) {
      const item = dataSource[id] || {};
      if (get(item, key) === value) {
        return field !== undefined ? get(item, field) : item;
      }
    }
  }
}

export function getFirstValidMenuPath(menus) {
  if (menus && menus.length) {
    for (const item of menus) {
      if (item.path) {
        return item.path;
      }
      const res = getFirstValidMenuPath(item.children);
      if (res) {
        return res;
      }
    }
  }
}

const id = getStoreId('MenuStore');
export const useMenuStore = defineStore(id, {
  state: () => ({
    menus: [],
    keyMenuEnum: {},
    routerKeyEnum: {},
    permissions: [],
    menuFieldsMap: {
      childrenKey: 'nodes',
      permissionKey: 'identification',
      titleKey: 'name',
      iconKey: 'img_url',
      key: 'id',
    },
  }),
  getters: {
    getMenuData(state) {
      return function () {
        return getMenuDataGetter.apply(state.keyMenuEnum, arguments);
      };
    },
    isPathHasPermission: (state) => (to) => {
      let permission = get(to, 'meta.permission');
      if (permission === undefined || permission === true) {
        return true;
      }
      if (!state.permissions || !state.permissions.length) {
        return false;
      }
      if (!Array.isArray(permission)) {
        permission = [permission];
      }
      return permission.some((item) => state.permissions.indexOf(item) >= 0);
    },
  },
  actions: {
    clearMenu() {
      this.$reset();
    },
    async getMenuAsync() {
      if (!isEmpty(this.menus)) {
        return;
      }
      const { childrenKey, permissionKey, titleKey, iconKey, key } = this.menuFieldsMap;
      let data = storage.session.getItem(USER_MENUS_KEY);
      if (isEmpty(data)) {
        const $axios = vueGlobal.get('$axios');
        const api = (params) => $axios.get('/xw-microservice/xw-system/v3/tpMenu/getTpMenu', { params });
        data = await handleCommonRes(api, null, {
          onFail: () => {
            vueGlobal.get('$message').error('菜单获取失败，请稍后再试！');
            this.menus = [];
            this.keyMenuEnum = {};
            this.permissions = [];
          },
        });
        storage.session.setItem(USER_MENUS_KEY, data, { expires: 1 });
      }
      const idtPathEnum = getPermissionKeyPathEnum();
      //能进行访问的页面
      this.permissions = flattenDeep(data, {
        deep: (item) => item[childrenKey],
        filter: (val) => !!val,
        format: (item) => trim(item[permissionKey]),
      });
      this.menus = replaceFields(data, {
        //路由地址,
        key: key,
        icon: iconKey,
        title: titleKey,
        path: (item) => idtPathEnum[trim(item[permissionKey])],
        children: childrenKey,
      });
      this.keyMenuEnum = getKeyMenuDataEnum(this.menus);
      this.routerKeyEnum = getRouterKeyDataEnum(this.menus);
    },
  },
});
